#include "qrcodeactivationwidget.h"
#include "ui_qrcodeactivationwidget.h"
#include <QNetworkConfigurationManager>
#include <QFileInfo>
#include <QProcess>
#include <QHostInfo>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QIcon>
#include <QGSettings>
#include <syslog.h>
#include <QUrl>
#include <QRegExpValidator>

QrCodeActivationWidget::QrCodeActivationWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QrCodeActivationWidget)
{
    ui->setupUi(this);
    ui->offlinewidget->setVisible(false);
    this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
    this->setProperty("useStyleWindowManager",false);
    ui->snlineEdit->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));
    ui->aclineEdit->setValidator(new QRegExpValidator(QRegExp("[A-Z0-9]+$")));

    activationiconlabel = new QLabel(this);
    activationremindlabel = new QLabel(this);
    activationiconlabel->setAlignment(Qt::AlignCenter);
    activationremindlabel->setAlignment(Qt::AlignCenter);
    activationremindlabel->setText(tr("Activating in progress"));

    activationiconlabel->setVisible(false);
    activationremindlabel->setVisible(false);

    m_timer=new QTimer;

    act_naManager = new QNetworkAccessManager(this);
    act_timer = new QTimer;
    count_time = 0;

    signalSlotConInit();
}

QrCodeActivationWidget::~QrCodeActivationWidget()
{
    delete m_timer;
    delete act_timer;
    delete ui;
}

void QrCodeActivationWidget::paintEvent(QPaintEvent *event)
{
    Interface interface;
    interface.setFontSize(ui->label);
}

void QrCodeActivationWidget::signalSlotConInit()
{
    //图像动画计时器
    connect(m_timer,&QTimer::timeout,this,[=]{
        static int cnt=0;
        Interface interface;
        QPixmap pixmap=interface.getThemeLoadingIcon(cnt);
        if(activationiconlabel->isVisible())
        {
            activationiconlabel->setPixmap(pixmap);
        }
        else{
            ui->qrcode->setPixmap(pixmap);
        }

        cnt++;
        if(cnt==7)
            cnt=0;
    });

    //网络检查与自动激活信号槽
    connect(act_naManager,&QNetworkAccessManager::finished,this,[=](QNetworkReply* reply){
        QNetworkReply::NetworkError err = reply->error();
        if(err == QNetworkReply::NoError) {
            if(_isCheckNet) {
                ui->remindlabel->setText(tr("Please scan the qr code below, and according to the prompt to complete the activation operation on mobile devices."));
                ui->offlinewidget->setVisible(false);
                m_checkIfOnLine=true;
                //申请自动激活
                act_naManager->get(act_request);
                if(!act_timer->isActive()) {
                    qDebug()<<"Start auto activation!";
                    act_timer->start(3000);
                }
            } else {
                QJsonParseError error;
                QJsonDocument readDoc=QJsonDocument::fromJson(reply->readAll(),&error);
                if(!readDoc.isNull() && error.error==QJsonParseError::NoError) {
                    if(0==readDoc.object().value("errcode").toInt()) {
                        QJsonObject obj=readDoc.object().value("data").toObject();
                        if(!obj.value("SERIAL").toString().isEmpty() && !obj.value("KEY").toString().isEmpty())
                            activeSys(obj.value("SERIAL").toString(),obj.value("KEY").toString().remove("-"));
                    }
                }
            }
        } else {
            ui->remindlabel->setText(tr("Unable to connect to the network, please scan the QR code below, enter the obtained serial number and activation code to activate."));
            ui->offlinewidget->setVisible(true);
            m_checkIfOnLine=false;
            ui->activebtn->setVisible(true);
            if(act_timer->isActive()) {
                act_timer->stop();
                qDebug()<<"Network exception, end auto activation!";
            }
        }
        reply->deleteLater();
        if(_isCheckNet) {
            //加载二维码
            m_timer->stop();
            initData();
            _isCheckNet=false;
        }
    });

    //自动激活计时器
    connect(act_timer, &QTimer::timeout, this, [=]{
        if(count_time >= 180000)
        {
            act_timer->stop();
            qDebug()<<"Time out, end auto activation!";
            count_time = 0;
            QMessageBox box(this);
            box.setIcon(QMessageBox::Information);
            box.setStandardButtons(QMessageBox::Retry);
            box.setText(QString(tr("Activation timed out! Please complete the activation on the mobile device, and then click retry button.")));
            int ret=box.exec();
            if(ret==QMessageBox::Retry)
            {
                count_time = 0;
                act_timer->start(3000);
            }
        }
        else{
            count_time += 3000;
            act_naManager->get(act_request);
            qDebug()<<" Start auto activation!";
        }
    });

}

//网络监测
void QrCodeActivationWidget::checkIfOnline()
{
    ui->offlinewidget->setVisible(false);
    ui->activebtn->setVisible(false);

    ui->qrcode->clear();
    ui->remindlabel->clear();
    ui->snlineEdit->clear();
    ui->aclineEdit->clear();

    //检查网络状态
    _isCheckNet=true;
    netRequestInit();
    act_naManager->get(act_request);

    m_timer->start(100);
}

void QrCodeActivationWidget::initData()
{
    if(!check_oem())
    {
        QStringList *rtnlist = NULL;
        if(can_set_serial())
        {
            canset_serial_flag = 1;
            rtnlist = byte8_get_init_data();//7位批次号
        }
        else
        {
            canset_serial_flag = 0;
            rtnlist = byte6_get_init_data();//8位服务序列号
        }

        if(rtnlist->at(5)== "0")
        {
            QFileInfo filepng("/tmp/kylin-qrcode.png");
            if(filepng.isFile())
                QFile::remove("/tmp/kylin-qrcode.png");
            QProcess p(0);
            QString qrurl = "qrencode -t png -s 188 -o /tmp/kylin-qrcode.png  ";
            qrurl.append(rtnlist->at(4));
            p.start(qrurl);
            p.waitForStarted();
            p.waitForFinished();
            ui->qrcode->setPixmap(QPixmap("/tmp/kylin-qrcode.png").scaled(QSize(188,188)));
            filepng.setFile("/tmp/kylin-qrcode.png");
            if(filepng.isFile())
                system("chmod 777 /tmp/kylin-qrcode.png");
         }
    }
    else
    {
        QFileInfo filepng("/tmp/kylin-qrcode.png");
        if(filepng.isFile())
            QFile::remove("/tmp/kylin-qrcode.png");
        QProcess p(0);
        QString qrurl = "qrencode -t png -s 188 -o /tmp/kylin-qrcode.png  ";
        QString url=QString("http://wx.kylinos.cn/distro/oem_activate?f=%1&v=%2&m=%3&s=%4")
                .arg(get_serial_number())
                .arg(get_vendor())
                .arg(get_model())
                .arg(get_service_tag());
        qDebug()<<"Qrcode url:"<<QUrl::toPercentEncoding(url,"/:&%=?"," ");
        qrurl.append(QUrl::toPercentEncoding(url,"/:&%=?"," "));
        p.start(qrurl);
        p.waitForStarted();
        p.waitForFinished();
        ui->qrcode->setPixmap(QPixmap("/tmp/kylin-qrcode.png").scaled(QSize(188,188)));
        filepng.setFile("/tmp/kylin-qrcode.png");
        if(filepng.isFile())
            system("chmod 777 /tmp/kylin-qrcode.png");
    }
}

void QrCodeActivationWidget::activeSys(QString serial, QString code)
{
    if(act_timer->isActive())
        act_timer->stop();
    gint activation= 1;
    QString ret = tr("Invalid activation code");
    if(canset_serial_flag == 0) {
        activation = active_code(code.toLatin1().data());
    } else {
        activation = new_active_code(serial.toLocal8Bit().data(), code.toLatin1().data());
    }
    ret = kylin_activation_get_result_message(activation);
    if(ret == "")
        ret = tr("Invalid activation code");
    if (activation == 0) {
        emit activationMessageSignal(activation);
        emit activateSucceed();
        if(act_timer->isActive()) {
            act_timer->stop();
        }
        qDebug()<<"Activate successfully, end auto activation!";
        exit_service();
    } else {
        QMessageBox::about(this,  NULL, QString(ret+ tr("!(error code#" )+ QString::number(activation).rightJustified(4,'0')  +")"));
        if(!act_timer->isActive())
            act_timer->start(3000);
    }
    m_timer->stop();
}

void QrCodeActivationWidget::on_returnbtn_clicked()
{
    m_timer->stop();
    act_timer->stop();
    count_time = 0;
    emit returnSignal();
}

void QrCodeActivationWidget::on_activebtn_clicked()
{
    m_timer->start(100);
    resetControlsState(0);
    int serialCheck=-1;
    int len=get_serial_number().length();
    if(7==len)//批次号，比较倒数二三位
    {
        QString serial=get_serial_number();
        QString serial_number=ui->snlineEdit->text();
        serialCheck=QString::compare(serial.mid(4,2),serial_number.mid(serial_number.length()-3,2));
    }
    else//比较服务序列号
    {
        serialCheck=QString::compare(ui->snlineEdit->text(),get_serial_number(),Qt::CaseSensitive);
    }

    if(serialCheck==0)
    {
        QString serial=ui->snlineEdit->text();
        QString code=ui->aclineEdit->text();
        if(code.length()==20)
            activeSys(serial,code);
    }
    else
    {
        QMessageBox *box=new QMessageBox(QMessageBox::Information, NULL, QString(tr("Invalid serial number!")),QMessageBox::NoButton,this);
        QPushButton *closeButton = box->addButton(tr("Close"), QMessageBox::AcceptRole);
        box->setDefaultButton(closeButton);
        box->exec();
        delete box;
    }
    m_timer->stop();
    resetControlsState(-1);
}

void QrCodeActivationWidget::resetControlsState(int type)
{
    if(type == 0)
    {
        ui->widget->layout()->removeWidget(ui->qrcode);
        ui->verticalLayout_4->insertWidget(1,activationiconlabel);
        ui->verticalLayout_4->insertWidget(2,activationremindlabel);
        activationiconlabel->setVisible(true);
        activationremindlabel->setVisible(true);
        ui->qrcode->setVisible(false);
    }
    else
    {
        ui->widget->layout()->removeWidget(activationiconlabel);
        ui->widget->layout()->removeWidget(activationremindlabel);
        ui->widget->layout()->addWidget(ui->qrcode);
        activationiconlabel->setVisible(false);
        activationremindlabel->setVisible(false);
        ui->qrcode->setVisible(true);
    }
}

void QrCodeActivationWidget::netRequestInit()
{
    QString url;
    if(check_oem())
        url=QString("https://wx.kylinos.cn/api/oem_activation.json?f=%1&v=%2&m=%3&s=%4")
                .arg(get_serial_number())
                .arg(get_vendor())
                .arg(get_model())
                .arg(get_service_tag());
    else
        url=QString("https://wx.kylinos.cn/api/get_activation.json?f=%1&y=%2")
                .arg(get_serial_number())
                .arg(get_encrypted_hardware_info());

    qDebug()<<"AUTO ACTIVATION URL:"<<QUrl::toPercentEncoding(url,"/:&%=?"," ");

    act_request.setUrl(QUrl(QUrl::toPercentEncoding(url,"/:&%=?"," ")));
}
